/*
*	Routine for delaying a specified amount of time (n seconds)
*
*	Author: ORC
*
* 	Copyright (c) Altera Corporation 2002.
* 	All rights reserved.
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>
#include <signal.h>

#include "timer1.h"
#include "errno.h"

#include <os/ostrace.h>
#include <os/interrupt.h>
#include <os/driver.h>
#include <machine/mmio.h>
#include <machine/machdefs.h>

#include "nmpt_defines.h"

volatile int timer_initval;
volatile int hsn_clockscale;

volatile int timer_type;
volatile timer_t timer_id;
volatile struct itimerspec  new_time,old_time;

void check_timer1()
{
	union sigval sigval = {0};

	uint32_t bit;

	if(get_timer_type() != FREE_TIMER){
		bit = *(volatile uint32_t*)(NMPT_INTR_CNTRL_BASE+NMPT_INTR_STATUS)&0x1;
		if(bit != 0){
			//isr_timer(sigval);//get the type of interrupt
		}
	}
}
uint32_t get_timer1_interrupt(){
	uint32_t bit;
	bit = *(volatile uint32_t*)(NMPT_INTR_CNTRL_BASE+NMPT_INTR_STATUS)&0x1;
	if(bit == 1){
		return 1;
	}
	return 0;
}

void init_timer1(void)
{
	*(uint32_t *)(NMPT_INTR_CNTRL_BASE + + 0x00) =  7 << 16;//select clk sources,Hsn_clk
	hsn_clockscale = (1<<16)/HSN_1USEC;
	//printf("HSN_1USEC = %d\n",HSN_1USEC);

	*(volatile uint32_t*)(NMPT_BASE+NMPT_START) = 0x0FFF;//(0xFFFFFF-HSN_1USEC*limit);
	*(volatile uint32_t*)(NMPT_BASE+NMPT_COMPARE) = 0;
	*(volatile uint32_t*)(NMPT_BASE+NMPT_CTRL) = 0x00003A6F;//0011 1010 0110 1111
	*(volatile uint32_t*)(NMPT_BASE) = 0; //presc
	*(volatile uint32_t*)(NMPT_BASE+NMPT_ADJ) = 0x00400000;//0000 0000 0100 0000 0000 0000 0000 0000

    set_timer_type(FREE_TIMER);
}

void start_timer1(){
	//enable
	*(volatile uint32_t*)(NMPT_BASE+NMPT_ADJ) = 1<<(1+22);//timer1

	/* Enable timer0 interrupts */
	*(volatile uint32_t*)(NMPT_INTR_CNTRL_BASE+NMPT_INTR_EN) = 0x1;
}

/* These files for Channel Acquiration Timer  and Ack Timer */
/** limit is in uSec **/
void set_timer1_limit(uint32_t limit)
{
	/*if hsn_clk=500M,timer one tick is (1/hsn_clk)us,
	  the time 7ms need ticks is:
	  7ms/(1/hsn_clk)us = 3500000 = 0x3567e0*/
	timer_initval =
	*(volatile uint32_t*)(NMPT_BASE+NMPT_START) = (0xFFFFFF-HSN_1USEC*limit);
	*(volatile uint32_t*)(NMPT_BASE+NMPT_COMPARE) = 0;
	*(volatile uint32_t*)(NMPT_BASE+NMPT_CTRL) = 0x00003A6F;//0011 1010 0110 1111
	*(volatile uint32_t*)(NMPT_BASE) = 0; //presc
	*(volatile uint32_t*)(NMPT_BASE+NMPT_ADJ) = 0x00400000;//0000 0000 0100 0000 0000 0000 0000 0000
}

uint32_t stop_timer1(void )
{
	uint32_t bit;
	uint32_t value;

	value = *(volatile uint32_t*)(NMPT_BASE+NMPT_START) - timer_initval;
	value = (value*hsn_clockscale) >> 16;

	*(volatile uint32_t*)(NMPT_BASE+NMPT_ADJ) = 0;//disable timer1

	/* If the timer already expired: clear the interrupt */
	bit = *(volatile uint32_t*)(NMPT_INTR_CNTRL_BASE+NMPT_INTR_STATUS)&0x1;
	if(bit != 0){
		*(volatile uint32_t*)(NMPT_INTR_CNTRL_BASE+NMPT_INTR_STATUS) = 0x1;
	}

	set_timer_type(FREE_TIMER);

	return value;
}

void clear_timer1_interrupt(){
	/* Disable timer0 interrupts */
	*(volatile uint32_t*)(NMPT_INTR_CNTRL_BASE+NMPT_INTR_EN) = 0x0;
	//*(volatile uint32_t*)(NMPT_INTR_CNTRL_BASE+NMPT_INTR_STATUS) & 0x01 = 0;
}
uint32_t current_timer1_value()
{
	uint32_t value;

	value = *(volatile uint32_t*)(NMPT_BASE+NMPT_START);// - timer_initval;
	//value = (value*hsn_clockscale) >> 16;

	return value;
}

void set_timer1_type(uint32_t type)
{
    timer_type=type;
}

uint32_t get_timer1_type()
{
    return timer_type;
}

